﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using AForge.Video.FFMPEG;
using CCWin;
using System.Collections;
using System.Globalization;
using System.Diagnostics;
using System.Runtime.InteropServices; 

namespace Counter
{
    
    public partial class frmCount : CCSkinMain
    {

        private bool paused = true;
        private int _id = 1;
        private ListViewColumnSorter lvwColumnSorter;

        public TimeSpan startTime;

        private void Pause()
        {
            int pos = (int)(this.playerRec.Ctlcontrols.currentPosition * 1000);
            this.trackMin.Value = pos / 1000 / 60 + 1;
            this.trackSec.Value = (pos / 1000) % 60 + 1;
            this.trackMillionSec.Value = (pos / 10) % 100 + 1;
            this.tbtnStop.Enabled = true;
            this.playerRec.Ctlcontrols.pause();
            this.tbtnPlay.Text = "开始";
            timerPlayTime.Stop();
            paused = true;
        }

        public void Start()
        {
            this.tbtnStop.Enabled = true;
            tbtnFastForward.Enabled = true;
            tbtnFastBackward.Enabled = true;
            tbtnFastBackward.Checked = false;
            tbtnFastForward.Checked = false;
            this.playerRec.Ctlcontrols.play();
            this.tbtnPlay.Text = "暂停";
            timerPlayTime.Start();
            paused = false;
        }
        public void ReCalcScore()
        {
            List<TimeSpan> orderList = new List<TimeSpan>();
            foreach (ListViewItem item in this.lstviewMembers.Items)
            {
                ListViewItem.ListViewSubItem subItem = item.SubItems[5];
                if (subItem.Tag != null)
                {
                    orderList.Add((TimeSpan)subItem.Tag);
                }
            }
            orderList.Sort();
            foreach (ListViewItem item in this.lstviewMembers.Items)
            {
                ListViewItem.ListViewSubItem subItem = item.SubItems[5];
                if (subItem.Tag != null)
                {
                    item.SubItems[6].Text = (orderList.IndexOf((TimeSpan)subItem.Tag) + 1).ToString();
                }
                else
                {
                    item.SubItems[6].Text = "0";
                }
            }
        }
        private void Stop()
        {
            this.tbtnPlay.Text = "开始";
            this.tbtnStop.Enabled = false;
            this.tbtnTrim.Enabled = false;
            this.tbtnTrim.Checked = false;
            tbtnFastForward.Enabled = false;
            tbtnFastBackward.Enabled = false;
            tbtnFastBackward.Checked = false;
            tbtnFastForward.Checked = false;
            this.playerRec.Ctlcontrols.stop();
            this.toolsPlaySetting.Enabled = false;
            this.toolsRecSettting.Enabled = true;
            this.splitContainer1.Enabled = false;
            timerPlayTime.Stop();
        }

        public void SetPosition(int pos)
        {
            int maxPos = this.trackLoc.Maximum - 1;
            this.trackLoc.Value = pos + 1;
            if (tbtnTrim.Checked)
            {
                this.trackMin.Value = pos / 1000 / 60 + 1;
                this.trackSec.Value = (pos / 1000) % 60 + 1;
                this.trackMillionSec.Value = (pos / 10) % 100 + 1;
            }
            if (paused)
            {
                this.tlabelInfo.Text = "已设定位置：" + new TimeSpan(pos * 10000);
                this.playerRec.Ctlcontrols.currentPosition = pos / 1000d;
            }
        }

        public frmCount()
        {
            InitializeComponent();
            this.tcomRecFile.Items.Clear();
            //初始化视频列表
            if (new DirectoryInfo(Application.StartupPath + "/Rec/").Exists)
            {
                foreach (var file in (new DirectoryInfo(Application.StartupPath + "/Rec/")).GetFiles("*.avi"))
                {
                    this.tcomRecFile.Items.Add(file.Name);
                }
                if (this.tcomRecFile.Items.Count > 0)
                {
                    this.tcomRecFile.SelectedIndex = this.tcomRecFile.Items.Count - 1;
                    tbtnSelRec_Click(tbtnSelRec, null);
                }
            }
            this.playerRec.uiMode = "none";
            this.playerRec.PlayStateChange += playerRec_PlayStateChange;
            this.playerRec.enableContextMenu = false;
            this.playerRec.settings.setMode("loop", true);
            lvwColumnSorter = new ListViewColumnSorter();
            this.lstviewMembers.ListViewItemSorter = lvwColumnSorter;
        }

        void playerRec_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
        {
            switch (e.newState)
            {
                case 1:
                    this.tlabelStatu.Text = "已停止";
                    Pause();
                    break;
                case 2:
                    this.tlabelStatu.Text = "已暂停";
                    Pause();
                    break;
                case 3:
                    this.trackLoc.Maximum = (int)(this.playerRec.currentMedia.duration * 1000) + 1;
                    this.trackMin.Maximum = (int)(this.playerRec.currentMedia.duration / 60) + 1;
                    this.numMin.Maximum = this.trackMin.Maximum - 1;
                    trackMin_ValueChanged(null, null);
                    trackSec_ValueChanged(null, null);
                    trackMillionSec_ValueChanged(null, null);
                    this.tlabelStatu.Text = "正在播放";
                    if (paused)
                    {
                        Start();
                    }
                    break;
                case 6:
                    this.tlabelStatu.Text = "正在缓冲";
                    break;
                case 9:
                    this.tlabelStatu.Text = "正在连接";
                    break;
                case 10:
                    this.tlabelStatu.Text = "准备就绪";
                    Start();
                    break;
                case 8:
                    this.tlabelStatu.Text = "播放完成";
                    break;
                default:
                    break;
            }
        }

        private void tbtnSelRec_Click(object sender, EventArgs e)
        {
            this.tlabelInfo.Text = "正在打开文件...";
            this.playerRec.URL = Application.StartupPath + "/Rec/" + this.tcomRecFile.Text;
            this.playerRec.Ctlcontrols.stop();
            this.tlabelInfo.Text = "打开文件成功！";
            this.toolsPlaySetting.Enabled = true;
            this.toolsRecSettting.Enabled = false;
            this.tbtnTrim.Enabled = true;
            this.splitContainer1.Enabled = true;

        }

        private void tbtnPlay_Click(object sender, EventArgs e)
        {
            if (tbtnPlay.Text == "开始")
            {
                Start();
            }
            else
            {
                Pause();
            }
        }

        private void tbtnStop_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void timerPlayTime_Tick(object sender, EventArgs e)
        {
            this.tlabelTime.Text = this.playerRec.Ctlcontrols.currentPositionString + "/" + this.playerRec.currentMedia.durationString;
            SetPosition((int)(this.playerRec.Ctlcontrols.currentPosition * 1000));
        }

        private void trackLoc_MouseUp(object sender, MouseEventArgs e)
        {
            timerTimeSet.Stop();
        }

        private void numMin_ValueChanged(object sender, EventArgs e)
        {
            this.trackMin.Value = (int)numMin.Value + 1;
        }

        private void numSec_ValueChanged(object sender, EventArgs e)
        {
            this.trackSec.Value = (int)numSec.Value + 1;
        }

        private void trackMin_ValueChanged(object sender, EventArgs e)
        {
            if (trackMin.Value == 0)
            {
                trackMin.Value = 1;
            }
            this.numMin.Value = this.trackMin.Value - 1;
            int maxPos = this.trackLoc.Maximum - 1 - (this.trackMin.Value - 1) * 60000;
            int maxSec = maxPos / 1000;
            if (maxSec > 60)
            {
                maxSec = 60;
            }
            this.trackSec.Maximum = maxSec + 1;
            this.numSec.Maximum = maxSec;
        }

        private void trackSec_ValueChanged(object sender, EventArgs e)
        {
            if (trackSec.Value == 0)
            {
                trackSec.Value = 1;
            }
            this.numSec.Value = this.trackSec.Value - 1;
            int maxPos = this.trackLoc.Maximum - 1 - (this.trackMin.Value - 1) * 60000 - (this.trackSec.Value - 1) * 1000;
            int maxSec = maxPos / 10;
            if (maxSec > 100)
            {
                maxSec = 100;
            }
            this.trackMillionSec.Maximum = maxSec + 1;
            this.numMillionSec.Maximum = maxSec;
        }

        private void trackMillionSec_ValueChanged(object sender, EventArgs e)
        {
            if (trackMillionSec.Value == 0)
            {
                trackMillionSec.Value = 1;
            }
            this.numMillionSec.Value = this.trackMillionSec.Value - 1;
        }

        private void trackLoc_ValueChanged(object sender, EventArgs e)
        {
            if (trackLoc.Value == 0)
            {
                trackLoc.Value = 1;
            }
        }

        private void trackLoc_MouseDown(object sender, MouseEventArgs e)
        {
            Pause();
            timerTimeSet.Start();
        }

        private void trackLoc_KeyDown(object sender, KeyEventArgs e)
        {
            Pause();
            timerTimeSet.Start();
        }

        private void trackMin_MouseUp(object sender, MouseEventArgs e)
        {
            SetPosition((this.trackMin.Value - 1) * 60000 + (this.trackSec.Value - 1) * 1000 + (this.trackMillionSec.Value - 1) * 10);
        }

        private void trackLoc_KeyUp(object sender, KeyEventArgs e)
        {
            SetPosition((this.trackMin.Value - 1) * 60000 + (this.trackSec.Value - 1) * 1000 + (this.trackMillionSec.Value - 1) * 10);
            timerTimeSet.Stop();
        }

        private void tbtnTrim_CheckedChanged(object sender, EventArgs e)
        {
            this.gpTrim.Visible = this.tbtnTrim.Checked;
        }

        private void numMillionSec_ValueChanged(object sender, EventArgs e)
        {
            this.trackMillionSec.Value = (int)this.numMillionSec.Value + 1;
        }

        private void tbtnFastForward_CheckedChanged(object sender, EventArgs e)
        {
            tbtnFastBackward.Checked = false;
            if (this.tbtnFastForward.Checked)
            {
                this.playerRec.Ctlcontrols.fastForward();
            }
            else
            {
                this.playerRec.Ctlcontrols.play();
            }
        }

        private void tbtnFastBackward_Click(object sender, EventArgs e)
        {
            tbtnFastForward.Checked = false;
            if (this.tbtnFastBackward.Checked)
            {
                this.playerRec.Ctlcontrols.fastReverse();
            }
            else
            {
                this.playerRec.Ctlcontrols.play();
            }
        }

        private void lstviewMembers_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                this.txtLineID.Text = item.SubItems[0].Text;
                this.txtID.Text = item.SubItems[2].Text;
                this.txtName.Text = item.SubItems[1].Text;
                this.txtStartTime.Text = item.SubItems[3].Text;
                this.txtArriveTime.Text = item.SubItems[4].Text;
                this.txtTag.Text = item.SubItems[7].Text;
                tbtnRemoveSel.Enabled = true;
                this.skinPanel3.Enabled = true;
            }
            else
            {
                this.skinPanel3.Enabled = false;
                tbtnRemoveSel.Enabled = false;
            }
        }

        private void tbtnAddMember_Click(object sender, EventArgs e)
        {
            ListViewItem item = new ListViewItem(_id++.ToString());
            item.SubItems.Add("未命名");
            item.SubItems.Add("0");
            ListViewItem.ListViewSubItem subItem = new ListViewItem.ListViewSubItem();
            TimeSpan startTime = new TimeSpan(this.startTime.Ticks);
            subItem.Tag = startTime;
            subItem.Text = startTime.ToString("g").Substring(2);
            item.SubItems.Add(subItem);
            item.SubItems.Add("未设置");
            item.SubItems.Add("条件不足");
            item.SubItems.Add("0");
            item.SubItems.Add("");
            lstviewMembers.Items.Add(item);
        }

        private void tbtnSelAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstviewMembers.Items)
            {
                item.Selected = true;
            }
        }

        private void tbtnUnselAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstviewMembers.Items)
            {
                item.Selected = false;
            }
        }

        private void tbtnReverseSel_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstviewMembers.Items)
            {
                item.Selected = !item.Selected;
            }
        }

        private void tbtnRemoveSel_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lstviewMembers.SelectedItems)
            {
                lstviewMembers.Items.Remove(item);
            }
        }

        private void txtID_SkinTxt_TextChanged(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                item.SubItems[2].Text = txtID.Text;
            }
        }

        private void txtName_SkinTxt_TextChanged(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                item.SubItems[1].Text = txtName.Text;
            }
        }
        private void skinTextBox1_SkinTxt_TextChanged_1(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                item.SubItems[7].Text = txtTag.Text;
            }
        }
        private void btnSetStartTime_Click(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                TimeSpan startTime = new TimeSpan((long)(playerRec.Ctlcontrols.currentPosition * 10000000));
                item.SubItems[3].Tag = startTime;
                item.SubItems[3].Text = startTime.ToString("g").Substring(2);
                this.txtStartTime.Text = item.SubItems[3].Text;
                if (item.SubItems[4].Tag != null)
                {
                    TimeSpan endTime = (TimeSpan)item.SubItems[4].Tag;
                    try
                    {
                        TimeSpan ts = endTime - startTime;
                        item.SubItems[5].Text = ts.ToString("g").Substring(2);
                    }
                    catch (Exception ex)
                    {
                        item.SubItems[5].Text = "计算出错：" + ex.Message;
                    }
                }
            }
        }
        private void btnSetArriveTime_Click(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                TimeSpan endTime = new TimeSpan((long)(playerRec.Ctlcontrols.currentPosition * 10000000));
                item.SubItems[4].Tag = endTime;
                item.SubItems[4].Text = endTime.ToString("g").Substring(2);
                this.txtArriveTime.Text = item.SubItems[4].Text;
                if (item.SubItems[3].Tag != null)
                {
                    TimeSpan startTime = (TimeSpan)item.SubItems[3].Tag;
                    try
                    {
                        TimeSpan ts = endTime - startTime;
                        item.SubItems[5].Text = ts.ToString("g").Substring(2);
                        item.SubItems[5].Tag = ts;
                    }
                    catch (Exception ex)
                    {
                        item.SubItems[5].Text = "计算出错：" + ex.Message;
                        item.SubItems[5].Tag = null;
                    }
                }
                ReCalcScore();
            }

        }
        private void skinTextBox1_SkinTxt_TextChanged(object sender, EventArgs e)
        {
            if (lstviewMembers.SelectedItems != null && lstviewMembers.SelectedItems.Count > 0)
            {
                ListViewItem item = lstviewMembers.SelectedItems[0];
                item.SubItems[0].Text = txtLineID.Text;
            }
        }
        private void frmCount_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("确定要关闭窗口么？未保存的记录将会丢失！", "确认关闭", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
        }

        private void lstviewMembers_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            ListView myListView = (ListView)sender;

            // Determine if clicked column is already the column that is being sorted.
            if (e.Column == lvwColumnSorter.SortColumn)
            {
                // Reverse the current sort direction for this column.
                if (lvwColumnSorter.Order == SortOrder.Ascending)
                {
                    lvwColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    lvwColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                // Set the column number that is to be sorted; default to ascending.
                lvwColumnSorter.SortColumn = e.Column;
                lvwColumnSorter.Order = SortOrder.Ascending;
            }

            // Perform the sort with these new sort options.
            myListView.Sort();
        }

        private void tbtnPrint_Click(object sender, EventArgs e)
        {
            string head =  info.comGroupType.Text + " " + info.comProject.Text + " " + info.comComID.Text + " " + info.comGroupID.Text;
            if (head != null && head != "")
            {
                if (!Directory.Exists(Application.StartupPath + @"\CSV\"))
                {
                    Directory.CreateDirectory(Application.StartupPath + @"\CSV\");
                }
                ListViewToCSV.ToCSV(lstviewMembers, Application.StartupPath + @"\CSV\" + head + ".csv", false);
                this.lstviewMembers.PrintHeaderString = head;
                Font f = this.lstviewMembers.Font;
                this.lstviewMembers.Font = this.lstviewMembers.HeaderFont;
                this.lstviewMembers.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
                this.lstviewMembers.AutoResizeColumn(7, ColumnHeaderAutoResizeStyle.ColumnContent);
                this.lstviewMembers.DoPrint();
                this.lstviewMembers.Font = f;
                this.lstviewMembers.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            }

        }

        private void tbtnSave_Click(object sender, EventArgs e)
        {
            saveFileDialog.ShowDialog();
        }

        private void saveFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            ListViewToCSV.ToCSV(lstviewMembers, saveFileDialog.FileName, false);
        }

        private void frmCount_FormClosed(object sender, FormClosedEventArgs e)
        {
            frmCap capForm = new frmCap(false);
            capForm.Show();
            this.Dispose();
        }

        private void frmCount_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 8; i++)
            {
                tbtnAddMember_Click(tbtnAddMember, new EventArgs());
            }
            //this.lstviewMembers.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            this.playerRec.Focus();
            //最大化窗口
            this.WindowState = FormWindowState.Maximized; 
        }

        private void frmCount_Shown(object sender, EventArgs e)
        {
            
        }

        private void timerTimeSet_Tick(object sender, EventArgs e)
        {
            SetPosition(this.trackLoc.Value - 1);
        }
          
        /// <summary>
        /// 快键注册部分, 空格播放视频， 回车暂停视频，加号记录成绩
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmCount_Activated(object sender, EventArgs e)
        {
            //注册热键Shift+S，Id号为100。HotKey.KeyModifiers.Shift也可以直接使用数字4来表示。
            HotKey.RegisterHotKey( Handle, 100, HotKey.KeyModifiers.Ctrl, Keys.Space);
            //注册热键Ctrl+B，Id号为101。HotKey.KeyModifiers.Ctrl也可以直接使用数字2来表示。
            HotKey.RegisterHotKey(Handle, 101, HotKey.KeyModifiers.None , Keys.F1 );
            //注册热键Alt+D，Id号为102。HotKey.KeyModifiers.Alt也可以直接使用数字1来表示。
            //HotKey.RegisterHotKey(Handle, 102, HotKey.KeyModifiers.None, Keys.S );
        }

        private void frmCount_Leave(object sender, EventArgs e)
        {
            //注销Id号为100的热键设定
            HotKey.UnregisterHotKey(Handle, 100);
            //注销Id号为101的热键设定
            HotKey.UnregisterHotKey(Handle, 101);
            //注销Id号为102的热键设定
            //HotKey.UnregisterHotKey(Handle, 102);
        }

        /// 
        /// 监视Windows消息
        /// 重载WndProc方法，用于实现热键响应
        /// 
        /// 
        protected override void WndProc(ref Message m)
        {

            const int WM_HOTKEY = 0x0312;
            //按快捷键 
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        case 100:    //按下的是Shift+S
                            //此处填写快捷键响应代码
                            if (this.paused) //播放状态   
                                this.Start(); 
                            else
                                this.Pause();
                            break;
                        case 101:    //按下的是Ctrl+B
                            //此处填写快捷键响应代码
                            this.btnSetArriveTime_Click(btnSetArriveTime , null  ) ; 
                            break;
                        case 102:    //按下的是Alt+D
                            //此处填写快捷键响应代码
                            break;
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        private void tbtnFastForward_Click(object sender, EventArgs e)
        {

        }
         
    }

    class HotKey
    {
        //如果函数执行成功，返回值不为0。
        //如果函数执行失败，返回值为0。要得到扩展错误信息，调用GetLastError。
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(
                        IntPtr hWnd,                //要定义热键的窗口的句柄
            int id,                     //定义热键ID（不能与其它ID重复）
            KeyModifiers fsModifiers,   //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
            Keys vk                     //定义热键的内容
            );
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(
            IntPtr hWnd,                //要取消热键的窗口的句柄
            int id                      //要取消热键的ID
            );
        //定义了辅助键的名称（将数字转变为字符以便于记忆，也可去除此枚举而直接使用数值）
        [Flags()]
        public enum KeyModifiers
        {
            None = 0,
            Alt = 1,
            Ctrl = 2,
            Shift = 4,
            WindowsKey = 8
        }
    }

}
